/*
 * Analyzer.cpp
 *
 *  Created on: 2011-03-26
 *      Author: kamil
 */

#include "Analyzer.h"
#include "mgr/config/Config.h"
#include "mgr/util/Vector2d.h"
#include "mgr/id/IdMgr.h"

log4cxx::LoggerPtr Analyzer::logger(log4cxx::Logger::getLogger("Analyzer"));

const double Analyzer::BALL_MOVED_DISTANCE = 0.5;
const double Analyzer::PLAYERS_NOT_MOVING_SPEED = 0.05;

GameInfo::GameInfo():
	playersMoving(false),
	lastBallContact(ModelId::UNDEFINED),
	ballMoved(false),
	ballOwned(false),
	ballOut(false)
{
}

Analyzer::Analyzer() {

}

Analyzer::~Analyzer() {

}

GameInfo Analyzer::analyze(std::map<ModelId, Videodata> & data){
	GameInfo info = lastGameInfo;
	ModelId ballId = Config::getBallInfo().id;
	Videodata ballData = data[ballId];
	Vector2d ballPos(ballData.x,ballData.y);

	std::map<ModelId, Videodata>::iterator i;

	//ball moved component
	if ((ballPos - savedBallPos).length() > BALL_MOVED_DISTANCE)
		info.ballMoved = true;

	LOG4CXX_DEBUG(logger, "BallPos: "<<ballPos);
	LOG4CXX_DEBUG(logger, "Game area: "<< Config::getFieldInfo().gameArea);
	if (Config::getFieldInfo().gameArea.contains(ballPos)){
		info.ballOut = false;
	}
	else if (!lastGameInfo.ballOut){
		info.ballOut = true;
		info.outPosition = ballPos;
	}

	//ball owned & touched calculation & robots moving
	for (i = data.begin(); i != data.end(); ++i){
		LOG4CXX_DEBUG(logger, "Analysis for model: "<<IdMgr::instance().getName(i->first));
		if (i->first == ballId) continue;

		Vector2d robotPos(i->second.x, i->second.y);
		double ballDist = (robotPos - ballPos).length();
		LOG4CXX_DEBUG(logger, "Robot pos: "<<robotPos);
		LOG4CXX_DEBUG(logger, "Ball dist: "<<ballDist);
		if (ballDist <= Config::getRobotInfo().radius + Config::getBallInfo().radius){
			info.ballOwned = true;
			info.lastBallContact = i->first;
		}
		else if (ballDist <= Config::getRobotInfo().radius + (2 * Config::getBallInfo().radius)	/* this may be to small margin */
				&& !info.ballOwned){
			info.lastBallContact = i->first;
		}

		Vector2d robotSpeed(i->second.vx, i->second.vy);
		if (robotSpeed.length() > PLAYERS_NOT_MOVING_SPEED) info.playersMoving = true;
	}

	lastGameInfo = info;


	return info;
}
